/***
 * @file GenExp.h Generator/GenExp.h
 *
 *  @author calle
 *  @date May 1, 2011
 *  
 *  @brief Generates an expression
 *
 *  An expression either  a
 *   - terminal
 *   - another expression (non terminal)
 *
 *  The terminal expressions are:
 *   - IdentExp IdentExpression
 *   - IntExp integer Expression
 *   - DoubleExp Double Expression
 *   - BoolExp Bool Expression
 *
 * @see IdentExp IntExp DoubleExp BoolExp genConstant
 */

#ifndef GENEXP_H_
#define GENEXP_H_


#include <Helpers/EnumHelper.h>
#include <Generator/TerminalState.h>
#include <Generator/Terminals.h>
#include <Helpers/ExpRegistry.h>
#include <AbsSyn/GenExpClasses/ExpressionType.h>
#include <boost/shared_ptr.hpp>
#include <AbsSyn/AbsSyn.h>
#include <Generator/context/IContext.h>
#include <iosfwd>
#include <AbsSyn/TypeEnum.h>

class IType;
class IExp;
class IContext;
class IdentExp;
//class AbsSyn;
/**
 * \class GenExp GenExp.h <Generator/GenExp.h>
 *
 * \brief Generator for randomly creating an expression.
 *
 * Generate Expressions are somewhat complicated, the first
 * choice is whether to make the expression complex or simple.
 * a complex expression is one that uses several other expressions (also called
 * non-terminal),
 * on the other hand a simple(also called terminal) is just made up of a constant.
 *
 * an example of a terminating expression can be a constant or an ident.
 * In this example we see such a expression
 *
 * a = 4000;
 * a = b;
 *
 * On the other hand a complex(non-terminal) can be made out of several expression
 * for example
 *
 * a = 4000 + 300 - 200;
 * or even using other ident's
 *
 * a = b + 3000 * 2;
 *
 * an expression that is just of a constant is called terminal, since it
 * terminates the expression. The nonterminal is for example +
 * which needs 2 more expression one on the right hand side and one on the left.
 *
 * <exp> + <exp>
 *
 * Now the rhs and the lhs can be non-terminal expressions too.
 * Which means that it creates a tree of expressions. The
 * Challenge of this class is to create that tree randomly.
 *
 *
 * \ingroup Generator
 *
 */

class GenExp  {
	public:

	/**
	 * \brief GenExp pointer to be used.
	 */
	typedef boost::shared_ptr< GenExp > GenExpPtr;
	/**
	 * \brief Enumeration for what kind of generation it should make.
	 *
	 * The default is RANDOM
	 */
	enum MODE {
			RANDOM,
			TERMINAL,
			NON_TERMINAL
		};

	GenExp(const ExpRegistry& registry,TypeEnum type,IContext* const currentContext, unsigned int depth);
	virtual ~GenExp();
	/**
	 * \brief This will create a tree of expression.
	 *
	 * A tree of expression will be created, the depth is
	 * for now not determined and is randomly created.
	 */
	AbsSyn::IExpPtr genExp(MODE mode=RANDOM);




private:




	AbsSyn::IExpPtr handleTerminal() const;
    AbsSyn::IExpPtr handleNonTerminal() const;


    AbsSyn::IExpPtr genConstant() const;

	/**
	 * \todo NEED TO FIX handleIdent, since we are now using ExpressionType instead!
	 */
    AbsSyn::IExpPtr handleIdent() const;

private:

	TerminalState m_Mode;
	const ExpRegistry& m_Registry;
	TypeEnum m_Type;
	IContext* m_currentContext;
	unsigned int m_Depth;




};



#endif /* GENEXP_H_ */
